<?php

namespace Framework;

use App\Constants\Common\HttpStatusCode;
use App\Http\Handler\RestMainHandler;
use FastRoute\Dispatcher;
use Framework\Facade\ConfigFacade;
use Framework\Foundation\Config;
use Framework\Foundation\Container\Container;
use Framework\Foundation\Log\Log;
use Framework\Foundation\Request\ServerRequest;
use Framework\Foundation\Response\ResponseGen;
use Framework\Foundation\Ini;
use Framework\Foundation\Rest\RestRequestInfo;
use Framework\Foundation\Route\RouterHelper;

class Frame
{
//    use FrameRoutePart;
    use FrameNewRoute;

    /**
     * @var Container;
     */
    protected $container;

    public function initConstants()
    {
        define('MIDDLEWARE_DIR', ROOT . '/Hierarchy/Middleware');
        define('HANDLER_DIR', ROOT . '/Hierarchy/Handler');
    }

    public function initConfig()
    {
        // 初始化env配置
        if (file_exists(ROOT . '/.ini')) {
            Ini::parseIniFile(ROOT . '/.ini');
        }
    }

    /**
     * web服务初始化
     */
    public function initWeb()
    {
        Log::init();

        $log = (new Foundation\Log\LoggerHelper())->getLogger("frame-zip");
        $reporter = new \Zipkin\Reporters\Log($log);
        $zip = new Foundation\Zipkin\ZipkinAssistant($reporter);
        Foundation\Log\ZipLog::setZipkin($zip);

        \think\facade\Db::setConfig(ConfigFacade::get('database', 'tp_config'));
    }

    public function run()
    {
        try {

            // 初始化路径常量
            $this->initConstants();
            // 初始化配置项目项
            $this->initConfig();

            $this->initWeb();

            $response = $this->appWorkFlow();
            ResponseGen::display($response);
        } catch (\Exception $e) {
            if (method_exists($e, 'getResponse')) {
                $response = $e->getResponse();
            } else {
                $response = ResponseGen::error($e->getCode(), $e->getMessage());
            }
            ResponseGen::display($response);
        }
    }

    public function appWorkFlow()
    {
        try {
            // 初始化ServerRequest对象
            $serverRequest = ServerRequest::fromGlobalsAndHandleJson();
            $routeHelper = new RouterHelper();
            $routeInfo = $routeHelper->extractRouteInfo($serverRequest);

            // 常规路由控制器
//            $dispatchInfo = $this->routeInitAndDispatch($routeInfo);
//            if ($dispatchInfo[0] == Dispatcher::FOUND) {
//                $request = $serverRequest->withAttribute('routeInfo', $routeInfo)->withAttribute(
//                    'dispatchInfo',
//                    $dispatchInfo
//                );
//                $response = MiddlewareRunner::runWithMiddleware($request, $dispatchInfo[1]['middleware'] ?? []);
//                return $response;
//            }

            // restFul路由控制器
            $restDispatchInfo = $this->restFulRouteInitAndDispatch($routeInfo);
            switch ($restDispatchInfo[0]) {
                case Dispatcher::METHOD_NOT_ALLOWED:
                    $response = ResponseGen::error(
                        HttpStatusCode::METHOD_NOT_ALLOWED,
                        'rest route result: method not allowed'
                    );
                    break;
                case Dispatcher::FOUND:
                    $restRequestInfo = new RestRequestInfo($routeInfo);
                    $request = $serverRequest->withAttribute(
                        'restDispatchInfo',
                        $restDispatchInfo
                    )->withAttribute('restRequestInfo', $restRequestInfo);
                    $response = MiddlewareRunner::runWithMiddleware(
                        $request,
                        $restDispatchInfo[1]['middleware'] ?? [],
                        RestMainHandler::class
                    );
                    break;
                case Dispatcher::NOT_FOUND:
                default:
                    $response = ResponseGen::error(
                        HttpStatusCode::NOT_FOUND,
                        HttpStatusCode::getCodeMessage(HttpStatusCode::NOT_FOUND)
                    );
                    break;
            }

            return $response;
        } catch (\Exception $e) {
            if (true === Config::instance()->get('app.debug')) {
                return ResponseGen::error($e->getCode(), $e->getMessage(), $e->getTrace());
            } else {
                return ResponseGen::error($e->getCode(), $e->getMessage());
            }
        }
    }

//    public function dispatchAndRun($routeInfo, $serverRequest)
//    {
//        $dispatchInfo = $this->routeInitAndDispatch($routeInfo);
//        if ($dispatchInfo[0] == Dispatcher::FOUND) {
//            $request = $serverRequest->withAttribute('dispatchInfo', $dispatchInfo);
//            return MiddlewareRunner::runWithMiddleware($request, $dispatchInfo[1]['middleware']);
//        }
//
//        $restDispatchInfo = $this->restFulRouteInitAndDispatch($routeInfo);
//        switch ($restDispatchInfo[0]) {
//            case Dispatcher::METHOD_NOT_ALLOWED:
//                return ResponseGen::error(HttpStatusCode::METHOD_NOT_ALLOWED, 'rest route result: method not allowed');
//                break;
//            case Dispatcher::FOUND:
//                // 运行路由中的前置中间件
//                $request = $serverRequest->withAttribute('restDispatchInfo', $restDispatchInfo);
//                return MiddlewareRunner::runWithMiddleware($request, $restDispatchInfo[1]['middleware'], RestMainHandler::class);
////                $response = $this->runPostMiddleware($dispatchInfo);
//                break;
//            case Dispatcher::NOT_FOUND:
//                break;
//        }
//        return null;
//    }
}
